package com.hunters.web.wechat.service.utils;

import com.platform.common.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.springframework.util.CollectionUtils;

import javax.net.ssl.SSLContext;
import java.io.*;
import java.net.URI;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * HttpClient工具类
 * 根据guess项目中的工具类修改。
 * <p>
 *
 * @author: WangYang
 * @date: 2017-11-22 14:25
 * @version: 1.0
 * @since 1.8
 */
@Slf4j
public class HttpClientHelper {

    /**
     * 默认编码
     */
    public static final String DEFAULT_CHARSET_ENCODING = "UTF-8";

    public static final boolean HTTP = false;

    public static final boolean HTTPS = true;

    /**
     * 基于SSL建立HttpClient
     *
     * @return
     */
    public static CloseableHttpClient createHttpClientBySSL() {
        try {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
                    (X509Certificate[] chain, String authType) -> true).build();
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext);
            return HttpClients
                    .custom()
                    .setSSLSocketFactory(sslConnectionSocketFactory)
                    .build();
        } catch (Exception e) {
            log.error("create https client error。", e);
        }
        return createHttpClient();
    }

    /**
     * 建立HttpClient
     *
     * @return
     */
    public static CloseableHttpClient createHttpClient() {
        return HttpClients.createDefault();
    }

    public static String get(String url, boolean ssl) {
        return get(url, DEFAULT_CHARSET_ENCODING, ssl);
    }

    public static String get(String url, String charsetEncoding, boolean ssl) {
        return get(url, ssl ? createHttpClientBySSL() : createHttpClient(), null, charsetEncoding);
    }

    public static String get(String url, Map<String, String> params, boolean ssl) {
        return get(url, ssl ? createHttpClientBySSL() : createHttpClient(), params, DEFAULT_CHARSET_ENCODING);
    }

    public static String get(String url, HttpClient httpClient, Map<String, String> params, String charsetEncoding) {
        String paramString = convertToString(params, charsetEncoding);
        url = StringUtils.isBlank(paramString) ? url : url + "?" + paramString;
        return doGet(URI.create(url), httpClient, charsetEncoding);
    }

    private static String doGet(URI uri, HttpClient httpClient, String charsetEncoding) {
        HttpGet httpGet = new HttpGet(uri);
        try {
            HttpResponse httpResponse = httpClient.execute(httpGet);
            InputStream in = httpResponse.getEntity().getContent();
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, charsetEncoding));
            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                sb.append(line);
            }
            in.close();
            return sb.toString();
        } catch (IOException e) {
            log.error("httpClient get request error.", e);
            throw new RuntimeException(e);
        } finally {
            HttpClientUtils.closeQuietly(httpClient);
        }
    }

    private static String convertToString(Map<String, String> params, String charsetEncoding) {
        List<NameValuePair> pairs = convertToNameValuePair(params);
        if (CollectionUtils.isEmpty(pairs)) {
            return null;
        }
        return URLEncodedUtils.format(pairs, charsetEncoding);
    }

    public static String post(String url, Map<String, String> params, boolean ssl) {
        return post(url, params, DEFAULT_CHARSET_ENCODING, ssl);
    }

    public static String post(String url, Map<String, String> params, String charsetEncoding, boolean ssl) {
        return post(url, ssl ? createHttpClientBySSL() : createHttpClient(), params, charsetEncoding);
    }

    public static String post(String url, HttpClient httpClient, Map<String, String> params, String charsetEncoding) {

        List<NameValuePair> pairs = convertToNameValuePair(params);
        return doPost(URI.create(url), httpClient, pairs, charsetEncoding);
    }

    private static String doPost(URI uri, HttpClient httpClient, List<NameValuePair> pairs, String charsetEncoding) {
        HttpPost httpPost = new HttpPost(uri);
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(pairs, charsetEncoding));
            HttpResponse httpResponse = httpClient.execute(httpPost);
            InputStream in = httpResponse.getEntity().getContent();
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, charsetEncoding));
            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                sb.append(line);
            }
            in.close();
            return sb.toString();
        } catch (IOException e) {
            log.error("httpClient post request error.", e);
            throw new RuntimeException(e);
        } finally {
            HttpClientUtils.closeQuietly(httpClient);
        }
    }

    private static List<NameValuePair> convertToNameValuePair(Map<String, String> params) {
        if (null == params || CollectionUtils.isEmpty(params.entrySet())) {
            return null;
        }
        return params.entrySet().stream()
                .map(item -> new BasicNameValuePair(item.getKey(), item.getValue()))
                .collect(Collectors.toList());
    }

    public static String jsonPost(URI uri, String json, String charsetEncoding) {
        HttpClient httpClient = HttpClients.createDefault();
        return doJsonPost(uri, httpClient, json, charsetEncoding);
    }

    public static String jsonPost(URI uri, Map<String, String> headers, String json, String charsetEncoding) {
        HttpClient httpClient = HttpClients.createDefault();
        return doJsonPost(uri, httpClient, json, charsetEncoding);
    }

    public static String jsonPost(URI uri, String json) {
        return jsonPost(uri, json, DEFAULT_CHARSET_ENCODING);
    }

    public static String jsonPost(String url, String json, String charsetEncoding) {
        URI uri = URI.create(url);
        return jsonPost(uri, json, charsetEncoding);
    }

    public static String jsonPost(String url, Map<String, String> headers, String json, String charsetEncoding) {
        URI uri = URI.create(url);
        return jsonPost(uri, headers, json, charsetEncoding);
    }

    public static String jsonPost(String url, String json) {
        return jsonPost(url, json, DEFAULT_CHARSET_ENCODING);
    }

    public static String jsonPost(String url, Map<String, String> headers, String json) {
        return jsonPost(url, headers, json, DEFAULT_CHARSET_ENCODING);
    }

    public static String sslJsonPost(URI uri, String json, String charsetEncoding) {
        HttpClient httpClient = createHttpClientBySSL();
        return doJsonPost(uri, httpClient, json, charsetEncoding);
    }

    public static String sslJsonPost(URI uri, String json) {
        return sslJsonPost(uri, json, DEFAULT_CHARSET_ENCODING);
    }

    public static String sslJsonPost(String url, String json, String charsetEncoding) {
        URI uri = URI.create(url);
        return sslJsonPost(uri, json, charsetEncoding);
    }

    public static String sslJsonPost(String url, String json) {
        return sslJsonPost(url, json, DEFAULT_CHARSET_ENCODING);
    }

    public static String xmlPost(URI uri, String xml, String charsetEncoding) {
        HttpClient httpClient = HttpClients.createDefault();
        return doXmlPost(uri, httpClient, xml, charsetEncoding);
    }

    public static String xmlPost(URI uri, String xml) {
        return jsonPost(uri, xml, DEFAULT_CHARSET_ENCODING);
    }

    public static String xmlPost(String url, String xml, String charsetEncoding) {
        URI uri = URI.create(url);
        return jsonPost(uri, xml, charsetEncoding);
    }

    public static String xmlPost(String url, String xml) {
        return jsonPost(url, xml, DEFAULT_CHARSET_ENCODING);
    }

    private static String doJsonPost(URI uri, HttpClient httpClient, String json, String charsetEncoding) {
        HttpPost httpPost = new HttpPost(uri);
        try {
            StringEntity stringEntity = new StringEntity(json, charsetEncoding);
            stringEntity.setContentType("application/json");
            httpPost.setEntity(stringEntity);
            HttpResponse httpResponse = httpClient.execute(httpPost);
            InputStream in = httpResponse.getEntity().getContent();
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, charsetEncoding));
            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                sb.append(line);
            }
            in.close();
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            HttpClientUtils.closeQuietly(httpClient);
        }
    }

    private static String doJsonPost(URI uri, Map<String, String> headers, HttpClient httpClient, String json, String charsetEncoding) {
        HttpPost httpPost = new HttpPost(uri);
        try {
            StringEntity stringEntity = new StringEntity(json, charsetEncoding);
            stringEntity.setContentType("application/json");
            httpPost.setEntity(stringEntity);
            headers.keySet().forEach(i -> {
                httpPost.setHeader(i, headers.get(i));
            });
            HttpResponse httpResponse = httpClient.execute(httpPost);
            InputStream in = httpResponse.getEntity().getContent();
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, charsetEncoding));
            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                sb.append(line);
            }
            in.close();
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            HttpClientUtils.closeQuietly(httpClient);
        }
    }

    private static String doXmlPost(URI uri, HttpClient httpClient, String json, String charsetEncoding) {
        HttpPost httpPost = new HttpPost(uri);
        try {
            StringEntity stringEntity = new StringEntity(json, charsetEncoding);
            stringEntity.setContentType("application/xml");
            httpPost.setEntity(stringEntity);
            HttpResponse httpResponse = httpClient.execute(httpPost);
            InputStream in = httpResponse.getEntity().getContent();
            StringBuilder sb = new StringBuilder();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in, charsetEncoding));
            for (String line = reader.readLine(); line != null; line = reader.readLine()) {
                sb.append(line);
            }
            in.close();
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            HttpClientUtils.closeQuietly(httpClient);
        }
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        //CryptoUtils desCrypto = new CryptoUtils();
        HashMap<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("userID", "admin");
        paramMap.put("password", "founder");
        paramMap.put("version", "1.0");
        paramMap.put("ismi", "123");
        paramMap.put("serviceName", "userLogin");
        final HashMap<String, String> map = new HashMap<String, String>();
        //CryptoUtils.encryptParams(map, paramMap);
        map.put("access_token", "g1-XgBh8GQVIpIj3u_GYj8d8I4hRbelGuPqVtQ-IkQvKuHHI-MrpAKX1lxnbAYVaKjmXBtteVHV_FmUDlPm_VtNxDo3JraayKcWjFoE76LQ");
        map.put("openid", "os712wgj6-95tMtV6Td4BLZsIEGg");
        String result = HttpClientHelper.post("https://api.weixin.qq.com/sns/auth", map, HttpClientHelper.HTTP);
        System.out.println(result);
//		Map<String,Object> resultMap = JSONObject.parseObject(result, Map.class);
//		System.out.println(resultMap.get("errcode"));
//		if(!"0".equals(resultMap.get("errcode").toString())){
//			System.err.println(resultMap.get("errcode"));
//		}
    }

}
